import json

from http import HttpError
from logic import Logic

class Server(object):
    def __init__(self, config):
        self.config = config
        def staticreply(filename, content_type):
            with open(filename) as file:
                reply = file.read()
                return [('Content-Type', content_type), ('Content-Length', str(len(reply)))], reply
        
        self.gets = \
            dict((path, staticreply(filename, content_type)) for 
                path, (filename, content_type) in
                config.staticfiles.iteritems())
                
        self.logic = Logic(config)

    def handle_get_config(self, environ, start_response):
        clientconfig = {
            'server_url': ('%s://%s' % (environ['wsgi.url_scheme'], environ['HTTP_HOST'])),
            'key': self.config.key,
            'magic': self.config.magic 
            }
        reply = 'var webhierarkia_config = %s;' % json.dumps(clientconfig)
        start_response('200 OK', [
            ('Content-Type', 'text/javascript'),
            ('Content-Length', str(len(reply)))])
        return reply
        
    def handle_get(self, environ, start_response):
        path = environ['PATH_INFO'].strip('/')
        if path == "config.js": return self.handle_get_config(environ, start_response)
        if path not in self.gets: raise HttpError(404)
        headers, reply = self.gets[path]        
        
        start_response('200 OK', headers)
        return reply
    
    def handle_post(self, environ, start_response):
        content_type = environ['CONTENT_TYPE']
        #if content_type != 'application/json': raise HttpError(415) # firefox does not send Content-Type in XMLHttpReq
        
        content_length = int(environ['CONTENT_LENGTH'])
        stream = environ['wsgi.input']

        jsonrequest = json.loads(stream.read(content_length))
        jsonreply = self.logic.request(jsonrequest)
        reply = json.dumps(jsonreply)
        
        start_response('200 OK',
            [
                ('Content-Type', 'application/json'),
                ('Content-Length', str(len(reply))),
                ('Cache-Control', 'no-cache'),
                ('Pragma', 'no-cache')
            ])
        return reply

        
    def wsgi_callback(self, environ, start_response):
        method = environ['REQUEST_METHOD']
        
        try:
            if method == 'GET': return self.handle_get(environ, start_response)
            elif method == 'POST': return self.handle_post(environ, start_response)
            
            raise HttpError(405)            
        except HttpError as error:
            start_response(
                '%d %s' % (error.code, error.msg),
                [
                    ('Content-type', error.content_type),
                    ('Allow', 'GET, POST')
                ]
                )
            return error.content if error.content is not None else error.msg

